﻿using System;
using System.Linq;
using System.Text;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using NLog.Web;
using Solution.EntityFrameworkCore;
using Web.CompressionProvider;
using Web.Filters;
using Web.Injection;

namespace Web
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public IContainer ApplicationContainer { get; private set; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options => {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => false;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });
            services.AddSession();

            services.AddMvc(options => { options.Filters.Add<HttpGlobalExceptionFilter>(); options.Filters.Add<CheckPermissionFilter>(); }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddHttpClient();
            services.Configure<ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders =
                    ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
            });
            services.AddResponseCompression(options =>
            {
                options.Providers.Add<BrotliCompressionProvider>();
                options.Providers.Add<GzipCompressionProvider>();
                options.EnableForHttps = true;
                options.MimeTypes =
                    ResponseCompressionDefaults.MimeTypes.Concat(
                        new[] { "image/svg+xml", "application/javascript", "application/json", "application/xml", "text/css", "text/json", "text/html" });
            });
            //services.AddDbContextPool<SolutionDbContext>(options =>

            //    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            services.AddDbContextPool<SolutionDbContext>(options => {
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
                //查询不带属性跟踪 提高查询效率
                options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
            });

            var builder = new ContainerBuilder();//实例化 AutoFac  容器
            builder.Populate(services);//管道寄居
            builder.RegisterModule(new Evolution());

            ApplicationContainer = builder.Build();// 构造
            return new AutofacServiceProvider(ApplicationContainer);//将autofac反馈到管道中

            //   services.AddScoped(typeof(IUnitOfWork), typeof(UnitOfWork));

            //  services.AddScoped<ISysUserRepository, SysUserRepository>();
            //services.AddScoped<IUserServices, UserServices>();

            //  services.AddScoped(typeof(ISysUserRepository), typeof(SysUserRepository));

            //   services.AddAssembly("Solution.Services");

            //   services.AddScoped(typeof(IRepositoryBase<>), typeof(BaseRepository<>));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime appLifetime, ILoggerFactory loggerFactory)
        {
            if (env.IsDevelopment()) {
                app.UseDeveloperExceptionPage();
            }
            else {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }
            app.UseStatusCodePagesWithRedirects("/Home/Error/{0}");
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseStatusCodePages();
            app.UseCookiePolicy();
            app.UseForwardedHeaders(new ForwardedHeadersOptions {
                ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            });
            app.UseSession();
            app.UseAuthentication();
            app.UseResponseCompression();
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            loggerFactory.AddNLog();//添加NLog
            env.ConfigureNLog("nlog.config");//读取Nlog配置文件

            app.UseMvc(routes => {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
            app.UseMvc(routes => {
                routes.MapRoute(
                    name: "areas",
                    template: "{area:exists}/{controller=Login}/{action=Index}/{id?}"
                );
            });

            appLifetime.ApplicationStopped.Register(() => { ApplicationContainer.Dispose(); });
        }
    }
}